﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Twi.COMMON.Core
{
    /*
    * Copyright: ©2010-2011 Twilight软件开发工作室版权所有
    * Author: xuzhihong
    * Create date: 2010-4-22
    * Description: Encryption Algorithm 加密算法
    * 
    */
    public class EncryptionAlgorithm
    {
        /// <summary>
        /// MD5
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetMD5(string str)
        {
            if (!string.IsNullOrEmpty(str))
            {
                return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5");
            }
            else
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// Base64编码 (已废弃，请使用Base64Encode方法代替)
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        [Obsolete]
        public static string ToBase64String(string str)
        {
            return EncryptionAlgorithm.Base64Encode(str);
        }

        /// <summary>
        /// Base64编码【加密】
        /// </summary>
        /// <param name="str">加密前的字符串</param>
        /// <returns>Base64加密后的字符串</returns>
        public static string Base64Encode(string str)
        {
            byte[] bytes = Encoding.Default.GetBytes(str);
            return Convert.ToBase64String(bytes);
        }

        /// <summary>
        /// Base64解码(已废弃，请使用Base64Decode方法代替)
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        [Obsolete]
        public static string FromBase64String(string str)
        {
            return EncryptionAlgorithm.Base64Decode(str);
        }

        /// <summary>
        /// Base64解码【解密】
        /// </summary>
        /// <param name="str">加密前的字符串</param>
        /// <returns>Base64加密后的字符串</returns>
        public static string Base64Decode(string str)
        {
            byte[] outputb = Convert.FromBase64String(str);
            string orgStr = Encoding.Default.GetString(outputb);
            return orgStr;
        }

        /// <summary>
        /// Base64自定义加密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string Base64CustomerEncode(string str)
        {
            //Base64加密
            str = EncryptionAlgorithm.Base64Encode(str);
            //反序
            IEnumerable<char> strChars = str.Reverse();
            
            //取随机数
            Random r = new Random();
            int randNum = r.Next(); 

            //将反序的按位异或
            str = Xor(strChars, randNum % 32);
            //Base64再加密一次
            str = EncryptionAlgorithm.Base64Encode(str);

            //随机数 Base64加密
            string strEncodeRandNum = EncryptionAlgorithm.Base64Encode(randNum.ToString());

            //最后将两个Base64加密后的使用分号（;）相加后的结果，再来一次Base64加密
            string lastStr = strEncodeRandNum + ";" + str;
            lastStr = EncryptionAlgorithm.Base64Encode(lastStr);
            return lastStr;
        }

        /// <summary>
        /// 将字符串字节按位异或。
        /// </summary>
        /// <param name="strChars">字符串的字节集合</param>
        /// <param name="num">异或数</param>
        /// <returns></returns>
        private static string Xor(IEnumerable<char> strChars, int num)
        {
            StringBuilder builder = new StringBuilder();
            foreach (var c in strChars)
            {
                int charVal = c;
                charVal ^= num;
                builder.Append((char)charVal);
            }
            return builder.ToString();
        }

        /// <summary>
        /// Base64自定义解密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string Base64CustomerDecode(string str)
        {
            //Base64解密
            str = EncryptionAlgorithm.Base64Decode(str);

            //拆分
            string[] arrStr = str.Split(';');
            //获取随机数
            int randNum = Convert.ToInt32(Base64Decode(arrStr[0]));
            //获取加密的字符串
            string needStr = EncryptionAlgorithm.Base64Decode(arrStr[1]);

            //按位异或
            needStr = Xor(needStr.ToList(), randNum % 32);

            //字符串反序
            char[] arrChars = needStr.Reverse().ToArray();
            needStr = "";
            foreach (var c in arrChars)
            {
                needStr += "" + c;
            }           

            //Base64解密
            needStr = EncryptionAlgorithm.Base64Decode(needStr);

            return needStr;
        }
    }
}
